#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
//建立两个管道,进程一自己执行完x,通过第一个管道向fxy进程写x,进程二自己执行完y,通过第二个管道向fxy写y;进程三两次读操作读x和y,完成相加后输出
int task3(int x,int y)
{
    return x+y;
}

int task1(int num)
{
    if(num == 1){
        return 1;
    }else{
        return task1(num-1)*num;
    }
}

int task2(int num)
{
    if(num == 1 || num == 2)
    {
        return 1;
    }else
    {
        return task2(num-1) + task2(num-2);
    }
    
}

int main(int arg,char* argv[])
{
    int pid=-1,pid2=-1,pid3=-1;
    int ix = 5,iy = 6;

    int args[2];
    int fx,fy;


    int fxy;
    
    int ppid = getpid();

    int pipe1[2];
    int pipe2[2];
    
    int i;
    for(i=1;i<3 && argv[i] != NULL; i++){
        printf("args[%d]=%d ",i-1,(int)atof(argv[i]));
        args[i-1] = (int)atof(argv[i]);
    }
    printf("\n");
    if(i != 3)
    {
        printf("no enough args and use x = 5,y = 6 for default\n");
    }else
    {
        ix = args[0];
        iy = args[1];
        printf("input x = %d,y = %d\n",ix,iy);
    }
    

    if(pipe(pipe1) < 0){
        perror("pipe not create\n");
        exit(EXIT_FAILURE);
    }
    if(pipe(pipe2) < 0){
        perror("pipe not create\n");
        exit(EXIT_FAILURE);
    }
    
    if(getpid() == ppid){
        printf("create process 1\n");
        pid = fork();//在主线程中创建执行fx的
    }

    if(getpid() == ppid){
        printf("create process 2\n");
        pid2 = fork();//在主线程中创建执行fy的
    }
    if(getpid() == ppid){
        printf("create process 3\n");
        pid3 = fork();//在主线程中创建执行fxy的
    }


    if(pid == 0)//执行f(x)
    {
        //子进程1负责从管道 1 的 1 端写
        close(pipe1[0]);
        close(pipe2[0]);
        close(pipe2[1]);
        printf("im f(x) process\n");
        fx = task1(ix);
        printf("over,fx=%d\n",fx);
        write(pipe1[1],&fx,sizeof(int));
    }

    if(pid2 == 0)//执行f(y)
    {
        //子进程2负责从管道 2 的 1 端写
        close(pipe2[0]);
        close(pipe1[0]);
        close(pipe1[1]);
        printf("im f(y) process\n");
        fy = task2(iy);
    	waitpid(pid,0,0); //等待子进程3结束
        printf("over,fy=%d\n",fy);
        write(pipe2[1],&fy,sizeof(int));
    }

    if(pid3 == 0)
    {
        //子进程3负责从管道 1 的 0 端读,管道2的0端读
        close(pipe1[1]);
        close(pipe2[1]);
        
        printf("im f(x,y) process\n");
        read(pipe1[0],&fx,sizeof(int));
        printf("read fx= %d\n",fx);
        read(pipe2[0],&fy,sizeof(int));
        printf("read fy= %d\n",fy);
        fxy = fx+fy;
        printf("fx+fy = %d\n",fxy);
	kill(getppid(),SIGINT);
    }
    if(pid != 0 && pid2 != 0){//主线程

	waitpid(pid3,0,0); //等待子进程3结束
        printf("im main process,now all calu is over\n");
    }
    return 0;
}


//注意,execve执行后的代码不会被执行.
